home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 176-200 / 190 / nethack / een.zoo / mkshop.c < prev    next >
C/C++ Source or Header  |  1988-07-23  |  10KB  |  315 lines

  1. /*      SCCS Id: @(#)mkshop.c   2.3     87/12/12
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  
  4. /*
  5.  * Entry points:
  6.  *      mkroom() -- make and stock a room of a given type
  7.  *      nexttodoor() -- return TRUE if adjacent to a door
  8.  *      has_dnstairs() -- return TRUE if given room has a down staircase
  9.  *      has_upstairs() -- return TRUE if given room has an up staircase
  10.  *      dist2() -- Euclidean square-of-distance function
  11.  *      courtmon() -- generate a court monster
  12.  *
  13.  * (note: this module should become mkroom.c in the next major release)
  14.  */
  15. #ifndef QUEST
  16. #include "hack.h"
  17. #include "mkroom.h"
  18. extern struct monst *makemon();
  19. extern struct permonst pm_soldier;
  20. extern struct obj *mkobj_at(), *mksobj_at();
  21. extern void stock_room();
  22. extern int nroom;
  23.  
  24. static boolean
  25. isbig(sroom)
  26. register struct mkroom *sroom;
  27. {
  28.         register int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly);
  29.         return( area > 20 );
  30. }
  31.  
  32. void
  33. mkroom(roomtype)
  34. /* make and stock a room of a given type */
  35. int     roomtype;
  36. {
  37.     void mkshop(), mkzoo(), mkswamp();
  38.  
  39.     if (roomtype >= SHOPBASE)
  40.         mkshop();       /* someday, we should be able to specify shop type */
  41.     else switch(roomtype)
  42.     {
  43.     case COURT: mkzoo(COURT); break;
  44.     case ZOO: mkzoo(ZOO); break;
  45.     case BEEHIVE: mkzoo(BEEHIVE); break;
  46.     case MORGUE: mkzoo(MORGUE); break;
  47.     case BARRACKS: mkzoo(BARRACKS); break;
  48.     case SWAMP: mkswamp(); break;
  49.     default:    impossible("Tried to make a room of type %d.", roomtype);
  50.     }
  51. }
  52.  
  53. static void
  54. mkshop(){
  55. register struct mkroom *sroom;
  56. int roomno, i = -1;
  57. #ifdef WIZARD
  58. extern char *getenv();
  59.  
  60.         /* first determine shoptype */
  61.         if(wizard){
  62.                 register char *ep = getenv("SHOPTYPE");
  63.                 if(ep){
  64.                         if(*ep == 'z' || *ep == 'Z'){
  65.                                 mkzoo(ZOO);
  66.                                 return;
  67.                         }
  68.                         if(*ep == 'm' || *ep == 'M'){
  69.                                 mkzoo(MORGUE);
  70.                                 return;
  71.                         }
  72.                         if(*ep == 'b' || *ep == 'B'){
  73.                                 mkzoo(BEEHIVE);
  74.                                 return;
  75.                         }
  76. #ifdef NEWCLASS
  77.                         if(*ep == 't' || *ep == 'T'){
  78.                                 mkzoo(COURT);
  79.                                 return;
  80.                         }
  81. #endif
  82. #ifdef SAC
  83.                         if(*ep == '3'){
  84.                                 mkzoo(BARRACKS);
  85.                                 return;
  86.                         }
  87. #endif /* SAC */
  88.                         if(*ep == 's' || *ep == 'S'){
  89.                                 mkswamp();
  90.                                 return;
  91.                         }
  92.                         for(i=0; shtypes[i].name; i++)
  93.                                 if(*ep == shtypes[i].symb) goto gottype;
  94.                         i = -1;
  95.                 }
  96.         }
  97. gottype:
  98. #endif
  99.         for(sroom = &rooms[0], roomno = 0; ; sroom++, roomno++){
  100.                 if(sroom->hx < 0) return;
  101.                 if(sroom - rooms >= nroom) {
  102.                         pline("rooms not closed by -1?");
  103.                         return;
  104.                 }
  105.                 if(sroom->rtype != OROOM) continue;
  106.                 if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom))
  107.                         continue;
  108.                 if(
  109. #ifdef WIZARD
  110.                    (wizard && getenv("SHOPTYPE") && sroom->doorct != 0) ||
  111. #endif
  112.                         sroom->doorct == 1) break;
  113.         }
  114.  
  115.         if(i < 0) {                     /* shoptype not yet determined */
  116.             register int j;
  117.  
  118.             /* pick a shop type at random */
  119.             for(j = rn2(100), i = 0; j -= shtypes[i].prob; i++)
  120.                 if (j < 0)      break;
  121.  
  122.             /* big rooms cannot be wand or book shops,
  123.              * - so make them general stores
  124.              */
  125.             if(isbig(sroom) && (shtypes[i].symb == WAND_SYM
  126. #ifdef SPELLS
  127.                                 || shtypes[i].symb == SPBOOK_SYM
  128. #endif
  129.                                                                 )) i = 0;
  130.         }
  131.         sroom->rtype = SHOPBASE + i;
  132.  
  133.         /* stock the room with a shopkeeper and artifacts */
  134.         stock_room(&(shtypes[i]), sroom);
  135. }
  136.  
  137. static void
  138. mkzoo(type)
  139. int type;
  140. {
  141.         register struct mkroom *sroom;
  142.         register struct monst *mon;
  143.         register int sh,sx,sy,i;
  144.         int goldlim = 500 * dlevel;
  145.         int moct = 0;
  146.         struct permonst *morguemon();
  147. #ifdef NEWCLASS
  148.         struct permonst *courtmon();
  149. #endif
  150.  
  151.         i = nroom;
  152.         for(sroom = &rooms[rn2(nroom)]; ; sroom++) {
  153.                 if(sroom == &rooms[nroom])
  154.                         sroom = &rooms[0];
  155.                 if(!i-- || sroom->hx < 0)
  156.                         return;
  157.                 if(sroom->rtype != OROOM)       continue;
  158.                 if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3)))
  159.                         continue;
  160.                 if(sroom->doorct == 1 || !rn2(5))
  161.                         break;
  162.         }
  163.         sroom->rtype = type;
  164.         sh = sroom->fdoor;
  165.         for(sx = sroom->lx; sx <= sroom->hx; sx++)
  166.             for(sy = sroom->ly; sy <= sroom->hy; sy++){
  167.                 if((sx == sroom->lx && doors[sh].x == sx-1) ||
  168.                    (sx == sroom->hx && doors[sh].x == sx+1) ||
  169.                    (sy == sroom->ly && doors[sh].y == sy-1) ||
  170.                    (sy == sroom->hy && doors[sh].y == sy+1)) continue;
  171.                 mon = makemon(
  172. #ifdef NEWCLASS
  173.                    (type == COURT) ? courtmon() :
  174. #endif
  175. #ifdef SAC
  176.                    (type == BARRACKS) ? PM_SOLDIER :
  177. #endif
  178.                    (type == MORGUE) ? morguemon() :
  179.                    (type == BEEHIVE) ? PM_KILLER_BEE : (struct permonst *) 0,
  180.                    sx, sy);
  181.                 if(mon) mon->msleep = 1;
  182.                 switch(type) {
  183.                 case ZOO:
  184.                    i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y));
  185.                    if(i >= goldlim) i = 5*dlevel;
  186.                    goldlim -= i;
  187.                    mkgold((long)(10 + rn2(i)), sx, sy);
  188.                    break;
  189.                 case MORGUE:
  190.                    /* Usually there is one dead body in the morgue */
  191.                    if(!moct && rn2(3)) {
  192.                         mksobj_at(CORPSE, sx, sy);
  193.                         moct++;
  194.                    }
  195.                    break;
  196.                 case BEEHIVE:
  197.                    if(!rn2(3)) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy);
  198.                    break;
  199.                 }
  200.         }
  201. #ifdef NEWCLASS
  202.         if(type == COURT)  {
  203.  
  204.                 sx = sroom->lx + (rn2(sroom->hx - sroom->lx));
  205.                 sy = sroom->ly + (rn2(sroom->hy - sroom->ly));
  206.                 RM_SET_TYP(levl[sx][sy], THRONE);
  207.                 levl[sx][sy].scrsym = THRONE_SYM;
  208.                 mkgold((long) rn1(50 * dlevel,10), sx, sy);
  209.         }
  210. #endif
  211.  
  212. }
  213.  
  214. static struct permonst *
  215. morguemon()
  216. {
  217.         extern struct permonst pm_ghost;
  218.         register int i = rn2(100), hd = rn2(dlevel);
  219.  
  220.         if(hd > 10 && i < 10) return(PM_DEMON);
  221.         if(hd > 8 && i > 85) return(PM_VAMPIRE);
  222.         return((i < 40) ? PM_GHOST : (i < 60) ? PM_WRAITH : PM_ZOMBIE);
  223. }
  224.  
  225. static void
  226. mkswamp()       /* Michiel Huisjes & Fred de Wilde */
  227. {
  228.         register struct mkroom *sroom;
  229.         register int sx,sy,i,eelct = 0;
  230.         extern struct permonst pm_eel;
  231.  
  232.         for(i=0; i<5; i++) {            /* 5 tries */
  233.                 sroom = &rooms[rn2(nroom)];
  234.                 if(sroom->hx < 0 || sroom->rtype != OROOM ||
  235.                    has_upstairs(sroom) || has_dnstairs(sroom))
  236.                         continue;
  237.  
  238.                 /* satisfied; make a swamp */
  239.                 sroom->rtype = SWAMP;
  240.                 for(sx = sroom->lx; sx <= sroom->hx; sx++)
  241.                 for(sy = sroom->ly; sy <= sroom->hy; sy++)
  242.                 if((sx+sy)%2 && !o_at(sx,sy) && !t_at(sx,sy)
  243.                              && !m_at(sx,sy) && !nexttodoor(sx,sy)){
  244.                         RM_SET_TYP(levl[sx][sy], POOL);
  245.                         levl[sx][sy].scrsym = POOL_SYM;
  246.                         if(!eelct || !rn2(4)) {
  247.                                 (void) makemon(PM_EEL, sx, sy);
  248.                                 eelct++;
  249.                         }
  250.                 }
  251.         }
  252. }
  253.  
  254. boolean
  255. nexttodoor(sx,sy)
  256. register sx,sy;
  257. {
  258.         register dx,dy;
  259.         register struct rm *lev;
  260.         for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++)
  261.                 if((lev = &levl[sx+dx][sy+dy]), RM_TYP(*lev) == DOOR ||
  262.                     RM_TYP(*lev) == SDOOR || RM_TYP(*lev) == LDOOR)
  263.                         return(TRUE);
  264.         return(FALSE);
  265. }
  266.  
  267. boolean
  268. has_dnstairs(sroom)
  269. register struct mkroom *sroom;
  270. {
  271.         return(sroom->lx <= xdnstair && xdnstair <= sroom->hx &&
  272.                    sroom->ly <= ydnstair && ydnstair <= sroom->hy);
  273. }
  274.  
  275. boolean
  276. has_upstairs(sroom)
  277. register struct mkroom *sroom;
  278. {
  279.         return(sroom->lx <= xupstair && xupstair <= sroom->hx &&
  280.                    sroom->ly <= yupstair && yupstair <= sroom->hy);
  281. }
  282.  
  283. int
  284. dist2(x0,y0,x1,y1){
  285.         return((x0-x1)*(x0-x1) + (y0-y1)*(y0-y1));
  286. }
  287.  
  288. static int
  289. sq(a) int a; {
  290.         return(a*a);
  291. }
  292. #endif /* QUEST /**/
  293.  
  294. #ifdef NEWCLASS
  295. struct permonst *
  296. courtmon()
  297. {
  298.         int     i = rn2(60) + rn2(3*dlevel);
  299.  
  300.         if (i > 100)            return(PM_DRAGON);
  301.         else if (i > 95)        return(PM_XORN);
  302.         else if (i > 85)        return(PM_TROLL);
  303.         else if (i > 75)        return(PM_ETTIN);
  304.         else if (i > 60)        return(PM_CENTAUR);
  305.         else if (i > 45)        return(PM_ORC);
  306.         else if (i > 30)        return(PM_HOBGOBLIN);
  307. #ifdef KOPS
  308.         else                    return(PM_GNOME);
  309. #else
  310.         else if (i > 15)        return(PM_GNOME);
  311.         else                    return(PM_KOBOLD);
  312. #endif
  313. }
  314. #endif /* NEWCLASS /**/
  315.